<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/11/29
 * Time: 18:55
 */

namespace app\api\service;


use app\api\model\User;
use app\lib\enum\ScopeEnum;
use app\lib\Exception\TokenException;
use app\lib\Exception\WxException;
use think\Exception;

/*
 * 用code 获取 openid & session_key
 * openid 存在数据库 不用生成新用户
 * 不存在  生成新纪录
 * md5生成token
 * 缓存token
 * */

class UserToken extends Token
{
    protected $appID;
    protected $appSecret;
    protected $code;
    protected $url;

    public function __construct($code)
    {
        $this->code = $code;
        $this->appID = config('wx.app_id');
        $this->appSecret = config('wx.app_secret');
        $this->url = sprintf(config('wx.login_url'), $this->appID, $this->appSecret, $this->code);
    }

    public function get()
    {
        // json
        $result = curl_get($this->url);

        // json转换为array
        $result = json_decode($result, true);

        if (empty($result)) {
            throw new Exception('获取session_key及openID异常，微信内部错误');
        } else {
            $errorExist = key_exists('errcode', $result);
            if ($errorExist) {
                // 出现错误
                $this->processWxError($result);
            } else {
                // 获取到openid和session_key
                // return token
                return $this->grantToken($result);
            }
        }
    }

    private function grantToken($result)
    {
        $openid = $result['openid'];

        // 数据库里有这个openid？
        $user = User::getByOpenId($openid);

        // 这个user存在了
        if ($user) {
            $uid = $user->id;
        } // 这个user不存在 插入数据
        else {
            $uid = $this->createUser($openid);
        }

        // 生成token 写入缓存 return
        $cache = $this->prepareCache($result, $uid);
        $token = self::saveCache($cache);
        return $token;
    }

    // private function saveCache($cache)
    // {
    //     $key = self::generateToken();
    //     // 数组转换为json
    //     $value = json_encode($cache);
    //     $expire= config('setting.token_expire_in');
    //     $result = cache($key,$value,$expire);
    //     if(!$result){
    //     // 缓存出错
    //         throw new TokenException([
    //             'info'=>'服务器缓存异常',
    //             'errorCode'=>10005
    //         ]);
    //     }
    //     return $key;
    // }

    private function prepareCache($result, $uid)
    {
        $result['uid'] = $uid;
        $result['scope'] = ScopeEnum::User;
        return $result;
    }

    private function createUser($openid)
    {
        $user = User::create([
            'openid' => $openid
        ]);

        return $user->id;
    }

    private function processWxError($result)
    {
        throw new WxException([
            'info'=>$result['errmsg'],
            'errorCode'=>$result['errcode']
        ]);
    }
}